home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / GRAPHICS / VGATUT4.ZIP / VGAPOLY.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1995-08-31  |  7.0 KB  |  321 lines

  1. /*────────────────────────────────────────────────────
  2.  
  3.     VGA POLYGONS - 4th in the VGA Programing tutorial
  4.            by Barny Mercer
  5.  
  6. ────────────────────────────────────────────────────*/
  7.  
  8. #include "..\include\vgafunc.cpp"
  9. #include "..\include\pallfunc.cpp"
  10. // #include "..\include\polyfunc.cpp"
  11.  
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <time.h>
  15.  
  16. // define polygon structure
  17. struct Point2D{ int X, Y; };
  18. static int StartX[200], EndX[200];
  19.  
  20. void DrawFillPolygon( Point2D *Polygon, int NumPoints, int Colour );
  21. void DrawFastFillPolygon( Point2D *Polygon, int NumPoints, int Colour );
  22. void PolyLine(int x1, int y1, int x2, int y2);
  23. void HorizLine( int Start, int End, int Y, unsigned char Col );
  24. void intro(void);
  25. void outro(void);
  26. void DrawRandomPolys();
  27.  
  28. void main(void)
  29. {
  30.     intro();
  31.  
  32.     VidMode(VID_320x200);
  33.  
  34.     DrawRandomPolys();
  35.  
  36.     VidMode(VID_TEXT);
  37.  
  38.     outro();
  39. }
  40.  
  41. void DrawFillPolygon( Point2D *Polygon, int NumPoints, int Colour )
  42. {
  43.     int i;
  44.     Point2D *NowPoint, *NextPoint;
  45.  
  46.     NowPoint = Polygon;
  47.     NextPoint = Polygon + 1;
  48.  
  49.     // clear polygon edge arrays
  50.     for (i=0; i<200; i++)
  51.     {
  52.     StartX[i] = -32000;
  53.     EndX[i] = -32000;
  54.     }
  55.  
  56.     for (i=1; i<NumPoints; i++)
  57.     {
  58.     PolyLine( NowPoint->X, NowPoint->Y, NextPoint->X, NextPoint->Y );
  59.  
  60.     NowPoint++;
  61.     NextPoint++;
  62.     }
  63.  
  64.     // now calculate last edge
  65.     NextPoint = Polygon;
  66.  
  67.     PolyLine( NowPoint->X, NowPoint->Y, NextPoint->X, NextPoint->Y);
  68.  
  69.     for (i=0; i<200; i++)
  70.     {
  71.     if (StartX[i] != -32000)
  72.     {
  73.         if (EndX[i] == -32000)
  74.         EndX[i] = StartX[i];
  75.  
  76.         DrawLine( StartX[i], i, EndX[i], i, Colour, vga );
  77.     }
  78.     }
  79. }
  80.  
  81. void DrawFastFillPolygon( Point2D *Polygon, int NumPoints, int Colour )
  82. {
  83.     int i;
  84.     Point2D *NowPoint, *NextPoint;
  85.  
  86.     NowPoint = Polygon;
  87.     NextPoint = Polygon + 1;
  88.  
  89.     // clear polygon edge arrays
  90.     for (i=0; i<200; i++)
  91.     {
  92.     StartX[i] = -32000;
  93.     EndX[i] = -32000;
  94.     }
  95.  
  96.     for (i=1; i<NumPoints; i++)
  97.     {
  98.     PolyLine( NowPoint->X, NowPoint->Y, NextPoint->X, NextPoint->Y );
  99.  
  100.     NowPoint++;
  101.     NextPoint++;
  102.     }
  103.  
  104.     // now calculate last edge
  105.     NextPoint = Polygon;
  106.  
  107.     PolyLine( NowPoint->X, NowPoint->Y, NextPoint->X, NextPoint->Y);
  108.  
  109.     for (i=0; i<200; i++)
  110.     {
  111.     if (StartX[i] != -32000)
  112.     {
  113.         if (EndX[i] == -32000)
  114.         EndX[i] = StartX[i];
  115.  
  116.         HorizLine( StartX[i], EndX[i], i, Colour );
  117.     }
  118.     }
  119. }
  120.  
  121. void PolyLine(int x1, int y1, int x2, int y2)
  122. {
  123.     int tmp, y;
  124.     long x, m;
  125.  
  126.     if (y2 != y1)
  127.     {
  128.     if (y2 < y1)
  129.     {
  130.         // swap values
  131.         tmp =  y1;
  132.         y1    =  y2;
  133.         y2    = tmp;
  134.  
  135.         tmp =  x1;
  136.         x1    =  x2;
  137.         x2    = tmp;
  138.     }
  139.  
  140.     x = (long)x1<<8;    // multiply x by 256
  141.  
  142.     m = ((long)(x2-x1)<<8)/((long)(y2-y1));    // gradient of line
  143.  
  144.     x += m;
  145.     y1++;
  146.  
  147.     for (y=y1; y<=y2; y++)
  148.     {
  149.         if ((y>=0) & (y<200))    // if co-ordinate is on screen
  150.         if (StartX[y] == -32000)
  151.             StartX[y] = x>>8;
  152.         else
  153.             EndX[y] = x>>8;
  154.  
  155.         x+=m;
  156.     }
  157.     }
  158. }
  159.  
  160. void HorizLine( int Start, int End, int Y, unsigned char Col )
  161. {
  162.     int Diff, Dir;
  163.  
  164.     _asm
  165.     {
  166.     mov [Dir], 1
  167.  
  168.     mov AX, [End]
  169.     sub AX, [Start]
  170.     mov [Diff], AX
  171.  
  172.     cmp [Diff], 0x00    ; we don't even want to bother trying to
  173.     jz  Finish        ; plot a line with no length
  174.  
  175.     cmp [Diff], 0x00
  176.     jg  Continue
  177.  
  178.     mov [Dir], 0xFFFF
  179.  
  180.     Continue:
  181.  
  182.     mov ax, 0xA000
  183.     mov es, ax
  184.     xor di, di
  185.  
  186.     mov bx, [Start]    ; co-ordinates
  187.     mov dx, [Y]
  188.     add di, bx
  189.     mov bx, dx
  190.     shl dx, 8
  191.     shl bx, 6
  192.     add dx, bx
  193.     add di, dx
  194.     mov al, [Col]
  195.  
  196.     mov cx, [Diff]
  197.  
  198.     Again:
  199.     mov es:[di], al    ;    put pixel at first point - address in ES:DI, colour in AL
  200.     add di, [Dir]
  201.  
  202.     sub cx, [Dir]
  203.     cmp cx, 0
  204.     jnz Again
  205.     Finish:
  206.     }
  207. }
  208.  
  209. void intro()
  210. {
  211.     VidMode( VID_TEXT );
  212.  
  213.     printf( "Hello & welcome to this, the fourth of my VGA programming tutorials\n" );
  214.     printf( "───────────────────────────────────────────────────────────────────\n\n" );
  215.     printf( "This edition concerns it's self with drawing filled polygons.\n");
  216.     printf( "The process is quite simple and quite a fast routine can be developed.\n");
  217.     printf( "\nThe first routine uses the standard line algorithm developed in Tutorial 2\n");
  218.     printf( "The second uses an optimised line routine (written in assembler)\n");
  219.     printf( "\n\nI will draw polygons for 10 seconds and then let you know how many have\n" );
  220.     printf( "been drawn. Please note that the number of polygons per second can vary greatly\n");
  221.     printf( "from one run to the next, so don't take these values as gospel.  Also note that ");
  222.     printf( "this is by no means the fastest polygon routine around, strive for more speed.\n" );
  223.     printf( "It should be easy to improve." );
  224.     printf( "\n\nTake a look.....\n");
  225.  
  226.     getch();
  227. }
  228.  
  229. void outro()
  230. {
  231.     VidMode( VID_TEXT );
  232.  
  233.     printf( "And there you have it!  Simple yet effective.\n\n");
  234.     printf( "HELP!  I don't know what to do for tutorial 5!  Help me out here!\n");
  235.     printf( "What would you like to see?  What areas of graphics programming interest you?\n\n");
  236.     printf( "Write to me at :  barny.mercer@zetnet.co.uk\n\n");
  237.     printf( "             while (!MailConcerningTutorial5Recieved())\n" );
  238.     printf( "             { \n" );
  239.     printf( "                  PanicLots(); \n" );
  240.     printf( "             }\n\n" );
  241.     printf( "             BreathSighOfRelief(); \n" );
  242.     printf( "             ProfuselyThankPersonWhoMadeSuggestion(); \n\n" );
  243.     printf( "Well... not strictly true, I do have a few ideas, but I would still like some\ninput." );
  244.     printf( "\n\nUntil next time.....\n\n");
  245. }
  246.  
  247. void DrawRandomPolys(void)
  248. {
  249.     Point2D Polygon[3];
  250.     time_t stime;
  251.     time_t NowTime;
  252.  
  253.     printf( "Original line routine...." );
  254.     getch();
  255.  
  256.     // number of polygons drawn
  257.     unsigned int NumPolys=0;
  258.  
  259.     // begin timing
  260.     time( &stime );
  261.     NowTime = stime;
  262.  
  263.     while( NowTime < (stime+10) )
  264.     {
  265.     for (int nTmp=0; nTmp<3; nTmp++)
  266.     {
  267.         Polygon[nTmp].X = (rand()%319);
  268.         Polygon[nTmp].Y = (rand()%199);
  269.     }
  270.  
  271.     DrawFillPolygon( Polygon, 3, rand()%256 );
  272.  
  273.     NumPolys++;
  274.     time( &NowTime );
  275.     }
  276.  
  277.     // check time at end
  278.     time( &NowTime );
  279.  
  280.     // clear keyboard buffer
  281.     getch();
  282.  
  283.     VidMode( VID_TEXT );
  284.     printf( "That's %d polygons in 10 seconds", NumPolys );
  285.     printf( "\nAbout %d polys per second", (NumPolys/10) );
  286.     getch();
  287.  
  288.     // faster polygon routine
  289.     VidMode( VID_320x200 );
  290.     printf( "Optimised line aglorithm...." );
  291.     getch();
  292.  
  293.     // begin timing
  294.     time( &stime );
  295.     NowTime = stime;
  296.  
  297.     while( NowTime < (stime+10) )
  298.     {
  299.     for (int nTmp=0; nTmp<3; nTmp++)
  300.     {
  301.         Polygon[nTmp].X = (rand()%319);
  302.         Polygon[nTmp].Y = (rand()%199);
  303.     }
  304.  
  305.     DrawFillPolygon( Polygon, 3, rand()%256 );
  306.  
  307.     NumPolys++;
  308.     time( &NowTime );
  309.     }
  310.  
  311.     // check time at end
  312.     time( &NowTime );
  313.  
  314.     getch();
  315.  
  316.     VidMode( VID_TEXT );
  317.     printf( "That's %d polygons in 10 seconds", NumPolys );
  318.     printf( "\nAbout %d polys per second", (NumPolys/10) );
  319.     getch();
  320. }
  321.